package com.ionehe.group.common.file.ex.service.impl;

import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.ionehe.group.common.file.ex.repository.dao.UserFileDao;
import com.ionehe.group.common.file.ex.repository.dao.UserFolderDao;
import com.ionehe.group.common.file.ex.repository.dataobject.UserFile;
import com.ionehe.group.common.file.ex.repository.dataobject.UserFolder;
import com.ionehe.group.common.file.ex.service.UserFileService;
import com.ionehe.group.common.file.ex.utils.FileUtil;
import com.ionehe.group.common.io.Response;
import com.ionehe.group.common.uaa.ex.enums.ErrorMessages;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;

/**
 * Copyright © 2020 moma有限公司
 * Date: 2020/9/23
 * Time: 上午9:40
 *
 * @author 2020年 <a href="mailto:chenwd@moma.ai">秀</a>
 * <p>
 * 操作user_file
 */
@Service
@Slf4j
public class UserFileServiceImpl implements UserFileService {
    @Resource
    private UserFileDao userFileDao;
    @Resource
    private UserFolderDao userFolderDao;

    private final Long fileMaxSize = 104857600L;

    @Override
    public Response<UserFile> createFile(UserFile userFile) {
        try {
            Preconditions.checkNotNull(userFile, ErrorMessages.FILE_NULL.toString());

            checkArgument(userFile.getSize() < fileMaxSize, ErrorMessages.USER_FILE_TOO_BIG.toString());

            UserFolder userFolder = userFolderDao.selectByPrimaryKey(userFile.getFolderId());

            checkArgument((0L == userFile.getFolderId() || null != userFolder), ErrorMessages.FOLDER_FOUND_FAIL.toString());

            userFile.setFileType(FileUtil.fileType(userFile.getName()).value());
            userFile.setCreatedAt(new Date());

            // 创建文件
            userFileDao.insert(userFile);

            log.info("UserFileService[]createFile[]success, userFile={}", userFile);

            return Response.yes(userFile);
        } catch (NullPointerException | IllegalArgumentException e) {
            log.error("UserFileService[]createFile[]error,userFile={}, cause={}",
                    userFile, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]createFile[]error,userFile={}, cause={}",
                    userFile, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_CREATE_FAIL.toString());
        }
    }

    @Override
    public Response<UserFile> findById(Long fileId) {
        try {
            UserFile userFile = userFileDao.selectByPrimaryKey(fileId);

            return Response.yes(userFile);
        } catch (NullPointerException e) {
            log.error("UserFileService[]findById[]error,fileId={}, cause={}",
                    fileId, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]findById[]error,fileId={}, cause={}",
                    fileId, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_FOUND_FAIL.toString());
        }
    }

    @Override
    public Response<Boolean> updateFile(UserFile userFile) {
        try {
            userFile.setUpdatedAt(new Date());

            Boolean isSuccess = userFileDao.updateByPrimaryKeySelective(userFile) < 1 ? Boolean.FALSE : Boolean.TRUE;

            log.info("UserFileService[]updateFile[]success, userFile={}", userFile);

            return Response.yes(isSuccess);
        } catch (NullPointerException e) {
            log.error("UserFileService[]updateFile[]error,userFile={}, cause={}",
                    userFile, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]updateFile[]error,userFile={}, cause={}",
                    userFile, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_UPDATE_FAIL.toString());
        }
    }

    @Override
    public Response<UserFile> deleteFile(Long fileId) {
        try {
            UserFile userFile = userFileDao.selectByPrimaryKey(fileId);

            userFileDao.deleteByPrimaryKey(fileId);

            log.info("UserFileService[]deleteFile[]success, fileId={}", fileId);

            return Response.yes(userFile);
        } catch (NullPointerException e) {
            log.error("UserFileService[]deleteFile[]error,fileId={}, cause={}",
                    fileId, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]deleteFile[]error,fileId={}, cause={}",
                    fileId, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_DELETE_FAIL.toString());
        }
    }

    @Override
    public Response<Boolean> moveFile(Long fileId, Long folderId) {
        try {
            UserFile userFile = userFileDao.selectByPrimaryKey(fileId);

            //UserFolder userFolder = userFolderDao.selectByPrimaryKey(folderId);
            userFile.setFolderId(folderId);

            Boolean isSuccess = userFileDao.updateByPrimaryKeySelective(userFile) < 1 ? Boolean.FALSE : Boolean.TRUE;

            log.info("UserFileService[]moveFile[]success, userFile={}", userFile);

            return Response.yes(isSuccess);
        } catch (NullPointerException | IllegalArgumentException e) {
            log.error("UserFileService[]moveFile[]error,fileId={}, cause={}",
                    fileId, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]moveFile[]error,fileId={}, cause={}",
                    fileId, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_MOVE_FAIL.toString());
        }
    }

    @Override
    public Response<UserFile> findByPath(String path) {
        try {
            UserFile userFile = new UserFile();

            userFile.setPath(path);

            userFile = userFileDao.selectOne(userFile);

            return Response.yes(userFile);
        } catch (NullPointerException | IllegalArgumentException e) {
            log.error("UserFileService[]findByPath[]findFile[]error,path={}, cause={}",
                    path, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]findByPath[]findFile[]error,path={}, cause={}",
                    path, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_FOUND_FAIL.toString());
        }
    }

    @Override
    public Response<List<UserFile>> findByFolderId(Long folderId) {
        try {
            UserFile userFile = new UserFile();

            userFile.setFolderId(folderId);

            List<UserFile> userFiles = userFileDao.select(userFile);

            return Response.yes(userFiles);
        } catch (NullPointerException e) {
            log.error("UserFileService[]findByFolderId[]findFile[]error, folderId={}, cause={}",
                    folderId, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]findByFolderId[]findFile[]error, folderId={}, cause={}",
                    folderId, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_FOUND_FAIL.toString());
        }
    }

    @Override
    public Response<String> getPathById(Long id) {
        try {
            UserFile uf = new UserFile();

            uf.setId(id);

            UserFile userFile = userFileDao.selectOne(uf);

            return Response.yes(userFile.getPath());
        } catch (NullPointerException e) {
            log.error("UserFileService[]getPathById[]error.id={}, cause={}",
                    id, e.getMessage());
            return Response.no(e.getMessage());
        } catch (Exception e) {
            log.error("UserFileService[]getPathById[]error.id={}, cause={}",
                    id, Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.FILE_FOUND_FAIL.toString());
        }
    }
}
